# 元类 一切类的类 type
# 一切皆对象
# type---实例化---》类---实例化---》对象
class People:
    def __init__(self, name, age):
        self.name = name
        self.age = age


print(type(People))
print(type(int))
print(type(str))

# class 创建类的过程
# 类的三个特质
# 类名
class_name = 'Person'
# 类的基类
class_bases = (object,)
# 执行类体得到的名称空间
class_dic = {}
class_body = """
def __init__(self, name, age):
    self.name = name
    self.age = age
def say(self):
    print("aaa")  
"""
exec(class_body, {}, class_dic)
print(class_dic)
# 通过class造类
print(type(class_name, class_bases, class_dic))
Person = type(class_name, class_bases, class_dic)


# 自定义元类
class Mymeta(type):  # 必须继承type类才是元类
    def __init__(self, x, y, z):
        print('init..')
        # print(self)
        # print(x)
        # print(y)
        # print(z)
        if not x.istitle():
            raise NameError('首字母必须大写')

    #         当前所在类，调用类是所传入的参数
    def __new__(cls, *args, **kwargs):
        # 必须返回对象才会 init初始化
        return type.__new__(cls, *args, **kwargs)


# 调用Mymet a
# People2 = Mymeta('People2', (object,), {...})
# 1.创建空对象==》People2，调用类中的__new__方法
# 2.调用Mymeta的__init__方法初始化对象
# 3.返回初始化对象

class People2(metaclass=Mymeta):
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def say(self):
        print("aaa")


# __call__
# 对象()->类内的__call__
# 类()->自定义元类的__call__
# 自定义元类()->内置元类__call__
class People3:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def say(self):
        print("aaa")

    def __call__(self, *args, **kwargs):
        print('()调用', args, kwargs)
        return 123


obj = People3('tom', 13)
res = obj(1, k=3)
print(res)

# 属性查找顺序
# 对象：类-》父类-》object类
# 类（作为对象调用属性）-》父类-》object类-》自定义元类
